package ;

import easelhx.display.BitmapAnimation;
import easelhx.display.SpriteSheet;
import easelhx.display.Stage;
import easelhx.display.Text;
import easelhx.js.Image;
import easelhx.utils.SpriteSheetUtils;
import easelhx.utils.Ticker;
import js.HTMLCanvasElement;
import js.Lib;

/**
 * ...
 * @author 
 */

class BitmapAnimationExample extends Example
{

	private var img:Image;
	private var bmpAnimList:Array<Dynamic>;
	
	public function new() 
	{
		super();
	}
	
	override public function run():Void 
	{
		img = new Image();
		img.onload = handleImageLoad;
		img.src = "assets/testSeq.png";
	}
	
	private function handleImageLoad(event) 
	{
		// grab canvas width and height for later calculations:
		var w:Float = canvas.width;
		var h:Float = canvas.height;
		
		// create spritesheet and assign the associated data.
		var spriteSheet:SpriteSheet  = new SpriteSheet({
			images: [img],
			frames: {width:64, height:68, regX:32, regY:34},
			animations: {
				walkUpRt:[0,19,"walkRt"],
				walkDnRt:[20,39,"walkUpRt"],
				walkRt:[41,59,"walkDnRt"]
			}
		});
		
		// to save file size, the loaded sprite sheet only includes right facing animations
		// we could flip the display objects with scaleX=-1, but this is expensive in most browsers
		// instead, we append flipped versions of the frames to our sprite sheet
		// this adds only horizontally flipped frames:
		SpriteSheetUtils.addFlippedFrames(spriteSheet, true, false, false);
		
		// we could rewire the "next" sequences to make them work like so:
		// but instead we will use code in the angleChange function.
		/*
		spriteSheet.getAnimation("walkDnRt").next = "walkDnRt_h";
		spriteSheet.getAnimation("walkDnRt_h").next = "walkRt_h";
		spriteSheet.getAnimation("walkRt_h").next = "walkUpRt_h";
		spriteSheet.getAnimation("walkUpRt_h").next = "walkUpRt";
		*/
		
		// create a BitmapAnimation instance to display and play back the sprite sheet:
		var bmpAnim:BitmapAnimation = new BitmapAnimation(spriteSheet);

		// start playing the first sequence:
		bmpAnim.gotoAndPlay("walkRt");		//animate

		// the callback is called each time a sequence completes:
		bmpAnim.onAnimationEnd = angleChange;

		// create a bunch of rats based on the first one, and place them on stage, and in our collection.
		var len = 50;
		bmpAnimList = new Array<Dynamic>();
		//for (i=0; i<l; i++) {
		for (i in 0 ... len) {
			bmpAnim.name = "rat" + i;
			Reflect.setField(bmpAnim, "speed", Math.random()*6+2);
			Reflect.setField(bmpAnim, "direction", 90);
			Reflect.setField(bmpAnim, "vX", Reflect.field(bmpAnim,"speed"));
			Reflect.setField(bmpAnim, "vY", 0);
			Reflect.setField(bmpAnim, "x", Math.random()*(w-220)+60);
			Reflect.setField(bmpAnim, "y", Math.random()*(h-220)+0);

			// have each rat start on a random frame in the "walkRt" animation:
			bmpAnim.currentAnimationFrame = Std.int( Math.random() ) * spriteSheet.getNumFrames("walkRt");
			stage.addChild(bmpAnim);
			bmpAnimList.push(bmpAnim);

			// rather than creating a brand new instance each time, and setting every property, we
			// can just clone the current one and overwrite the properties we want to change:
			if (i < len-1) { bmpAnim = cast bmpAnim.clone(); }
		}

		// we want to do some work before we update the canvas,
		// otherwise we could use Ticker.addListener(stage);
		Ticker.addListener(this);
	}
	
	// called if there is an error loading the image (usually due to a 404)
	function handleImageError(e) {
		//console.log("Error Loading Image : " + e.target.src);
		Lib.alert("Error Loading Image : " + e.target.src);
	}

	function tick() {
		// move all the rats according to their vX/vY properties:
		var len = bmpAnimList.length;
		for (i in 0 ... len) {
			var bmpAnim = bmpAnimList[i];
			bmpAnim.x += bmpAnim.vX;
			bmpAnim.y += bmpAnim.vY;
		}
		// update the stage:
		stage.update();
	}

	function angleChange(bmpAnim,animation) {
		//after each sequence ends update the rat's heading and adjust velocities to match
		bmpAnim.direction -= 60;
		var angle = bmpAnim.direction * (Math.PI/180);
		bmpAnim.vX = Math.sin(angle) * bmpAnim.speed;
		bmpAnim.vY = Math.cos(angle) * bmpAnim.speed;
		var nextMap:Dynamic = {walkRt:"walkDnRt",walkDnRt:"walkDnRt_h",walkDnRt_h:"walkRt_h",walkRt_h:"walkUpRt_h",walkUpRt_h:"walkUpRt",walkUpRt:"walkRt"};
		bmpAnim.gotoAndPlay(nextMap[animation]);
	}
	
}